package bibbletex.helpers;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;

import org.xml.sax.*;
import org.xml.sax.helpers.*;
import javax.xml.parsers.*;

public class ParseDetails extends DefaultHandler {

	/** Character Data innerhalb des aktuellen Tags. */
	private StringBuffer stringBuffer = null;
	private String site = "";

	public ParseDetails(String path) {
		// currentItem wird in startElement initialisiert
		stringBuffer = new StringBuffer();
		try {
			// Neuen SAX-Parser erzeugen
			SAXParserFactory factory = SAXParserFactory.newInstance();

			factory.setValidating(false);
			factory.setNamespaceAware(true);
			factory.setFeature(
					"http://apache.org/xml/features/nonvalidating/load-external-dtd",
					false);

			// Parser erzeugen
			SAXParser saxParser = factory.newSAXParser();

			// XML einlesen
			URL website = new URL(path);
			BufferedReader in = new BufferedReader(new InputStreamReader(
					website.openStream()));

			String site = "";
			String inputLine;

			while ((inputLine = in.readLine()) != null)
				site += inputLine + "\n";

			in.close();

			// linebreaks ändern -> unnötig
			// site = site.replace("\r\n","\n");

			// & Paramater - Fehler umgehen
			// könnte mit anderen Entitäten in Konflikt stehen: &auml; ->
			// &amp;auml;
			site = site.replace("&", "&amp;");

			// nicht deklarierte Entitäten durch numerische Referenz ersetzen
			// & -> &amp; - Korrektur berichtigen ;)
			site = site.replace("&amp;auml;", "&#228;");
			site = site.replace("&amp;ouml;", "&#246;");
			site = site.replace("&amp;uuml;", "&#252;");
			site = site.replace("&amp;szlig;", "&#223;");
			site = site.replace("&amp;Auml;", "&#196;");
			site = site.replace("&amp;Ouml;", "&#214;");
			site = site.replace("&amp;Uuml;", "&#220;");
			site = site.replace("&amp;nbsp;", "&#160;");
			site = site.replace("selected", "");
			site = site.replace("<tr id=\"docVenue\">", "<tr id=\"docVenue\"></tr>");

			InputStream instream = new ByteArrayInputStream(site.getBytes());

			// Codierungsprobleme umgehen [UTF-8]
			InputSource source = new InputSource(
					prepareInputStreamReader(instream));

			// vorbereitete Version parsen
			// XML Datei parsen, die entsprechenden Methoden des DefaultHandler
			// werden als Callback aufgerufen.

			// System.out.println("Parsing " + path);
			saxParser.parse(source, this);

		} catch (Exception e) {
			
		}
	}

	// ungültige Zeichen durch "?" ersetzen
	private Reader prepareInputStreamReader(InputStream inputStream) {
		// Strip all invalid UTF-8 sequences from input
		CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
		decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
		decoder.onMalformedInput(CodingErrorAction.REPLACE);
		decoder.replaceWith("?");

		return new InputStreamReader(inputStream, decoder);
	}

	boolean code = false;
	boolean startRead = false;
	// Behandlung der Start-Tags
	public void startElement(String namespaceURI, String localName,
			String qName, Attributes atts) throws SAXException {
		if(qName.equals("div")){
			for(int i = 0; i<atts.getLength(); i++){
				if (atts.getQName(i).equals("id") && atts.getValue(i).equals("bibtex")){
					code = true;
				}
			}
		}
		if(qName.equals("p") && code){
			startRead = true;
		}
		stringBuffer.setLength(0);
	}

	// Behandlung der End-Tags
	public void endElement(String namespaceURI, String localName, String qName) {
		if(qName.equals("p")){
			startRead = false;
			code = false;
			
		}
	}

	// Behandlung des Inhalts zwischen den Tags
	public void characters(char ch[], int start, int length) {
		if(startRead){
			for( int i = start; i< start+length; i++){
				site += ch[i];
			}
		}
	}
	
	public void endDocument(){
		
	}

	public String getSite() {
		site.replace("<br/>","");
		site.replace("&nbsp;","");

		return this.site;
	}
}
